﻿/// <reference path="../MicrosoftAjax.Debug.js" />
/// <reference path="../jquery-1.8.3.js" />
// ************** TreePanel定义
Type.registerNamespace('ExtJSExtender.Controls');

ExtJSExtender.Controls.TreePanelExtenderBehavior = function (element) {
    ExtJSExtender.Controls.TreePanelExtenderBehavior.initializeBase(this, [element]);
}

ExtJSExtender.Controls.TreePanelExtenderBehavior.prototype = {
    _ExtControl: null,
    _BehaviorState: {},
    _TriggerPostBackEvents: null,
    initialize: function () {
        ExtJSExtender.Controls.TreePanelExtenderBehavior.callBaseMethod(this, 'initialize');
        var id = this.get_element().id;
        var self = this;
        var rootText = this.get_RootText();
        var rootNodeData = Ext.JSON.decode($('#' + this.get_NodeValueHiddenField()).val());
        self._BehaviorState = Ext.JSON.decode($('#' + this.get_BehaviorStateHiddenField()).val());

        var cfg = {
            title: this.get_Title(),
            rootVisible: rootText.length > 0,
            border: this.get_Border(),
            useArrows: this.get_UseArrows(),
            disabled: !self.get_Enabled(),
            listeners: {
                'beforeload': Function.createDelegate(self, self.raiseBeforeLoad),
                'load': function () {
                    self.storeData();
                },
                'itemclick': Function.createDelegate(self, self.raiseItemClick),
                'itemcollapse': Function.createDelegate(self, self.raiseItemCollapse),
                'itemexpand': Function.createDelegate(self, self.raiseItemExpand),
                'checkchange': Function.createDelegate(self, self.raiseItemCheckChange)
            },
            renderTo: id
        };
        if (this.get_Height()) cfg.height = this.get_Height();
        if (this.get_Width()) cfg.width = this.get_Width();

        var storeCfg = {
            root: rootNodeData
        }
        if (this.get_DataUrl()) {
            storeCfg.proxy = {
                type: 'ajax',
                url: this.get_DataUrl()
            };
        }

        //绘制控件
        Ext.onReady(function () {
            var treeStore = Ext.create('Ext.data.TreeStore', storeCfg);
            cfg.store = treeStore;
            var treePanel = Ext.create('Ext.tree.Panel', cfg);
            self._ExtControl = treePanel;

            if (self._BehaviorState.SelectedPath)
                self.selectPath(self._BehaviorState.SelectedPath); //self.select(selectedNodeId);

            var queryEl = $(self._ExtControl.getView().el.dom);
            //设置控件滚动条的位置
            if (self._BehaviorState.ScrollX > 0) queryEl.scrollLeft(self._BehaviorState.ScrollX);
            if (self._BehaviorState.ScrollY > 0) queryEl.scrollTop(self._BehaviorState.ScrollY);
            //添加滚动条滚动事件
            queryEl.unbind('scroll').scroll(function () {
                self._BehaviorState.ScrollX = event.srcElement.scrollLeft;
                self._BehaviorState.ScrollY = event.srcElement.scrollTop;
                self.storeBehaviorState();
            });
        }, this);
    },
    dispose: function () {
        ExtJSExtender.Controls.TreePanelExtenderBehavior.callBaseMethod(this, 'dispose');
    },
    get_Title: function () {
        return this._Title;
    },
    set_Title: function (value) {
        this._Title = value;
    },
    get_Enabled: function () {
        return this._Enabled;
    },
    set_Enabled: function (value) {
        this._Enabled = value;
    },
    get_Width: function () {
        return this._Width;
    },
    set_Width: function (value) {
        this._Width = value;
    },
    get_Height: function () {
        return this._Height;
    },
    set_Height: function (value) {
        this._Height = value;
    },
    get_Border: function () {
        return this._Border;
    },
    set_Border: function (value) {
        this._Border = value;
    },
    get_UseArrows: function () {
        return this._UseArrows;
    },
    set_UseArrows: function (value) {
        this._UseArrows = value;
    },
    get_DataUrl: function () {
        return this._DataUrl;
    },
    set_DataUrl: function (value) {
        this._DataUrl = value;
    },
    get_RootId: function () {
        return this._RootId;
    },
    set_RootId: function (value) {
        this._RootId = value;
    },
    get_RootText: function () {
        return this._RootText;
    },
    set_RootText: function (value) {
        this._RootText = value;
    },
    get_AutoPostBack: function () {
        return this._AutoPostBack;
    },
    set_AutoPostBack: function (value) {
        this._AutoPostBack = value;
    },
    get_NodeValueHiddenField: function () {
        return this._NodeValueHiddenField;
    },
    set_NodeValueHiddenField: function (value) {
        this._NodeValueHiddenField = value;
    },
    get_BehaviorStateHiddenField: function () {
        return this._BehaviorStateHiddenField;
    },
    set_BehaviorStateHiddenField: function (value) {
        this._BehaviorStateHiddenField = value;
    },
    get_NodeClickedEvent: function () {
        return this._NodeClickedEvent;
    },
    set_NodeClickedEvent: function (value) {
        this._NodeClickedEvent = value;
    },
    get_NodeCheckedEvent: function () {
        return this._NodeCheckedEvent;
    },
    set_NodeCheckedEvent: function (value) {
        this._NodeCheckedEvent = value;
    },
    get_UniqueID: function () {
        return this._UniqueID;
    },
    set_UniqueID: function (value) {
        this._UniqueID = value;
    },
    get_TriggerPostBackEvents: function () {
        return this._TriggerPostBackEvents;
    },
    set_TriggerPostBackEvents: function (value) {
        this._TriggerPostBackEvents = value;
    },
    select: function (id) {
        var self = this;
        var root = this._ExtControl.getRootNode();

        var processChild = function (node, id) {
            if (node.data.id == id) {
                self._ExtControl.selectPath(node.getPath());
                return false;
            }
            else {
                node.eachChild(function (childNode) {
                    return processChild(childNode, id);
                }, this);
            }
        }

        processChild.call(this, root, id);
    },
    selectPath: function (path) {
        this._ExtControl.selectPath(path);
    },
    toJsonString: function (node) {
        var rootNode = node;
        var rootData = $.extend({}, rootNode.data);
        //rootData.text = encodeURIComponent(rootData.text);
        this.serialzeChildren(rootData, rootNode);
        return Ext.encode(rootData);
    },
    serialzeChildren: function (parentData, parentNode) {
        parentData.children = [];
        parentNode.eachChild(function (node) {
            if (node.raw) {
                var data = $.extend({}, node.data);
                //data.text = encodeURIComponent(data.text);
                parentData.children.push(data);
                this.serialzeChildren(data, node)
            }
        }, this);
    },
    storeData: function () {
        //持久化所有节点
        $('#' + this.get_NodeValueHiddenField()).val(this.toJsonString(this._ExtControl.getRootNode()));
    },
    storeBehaviorState: function () {
        $('#' + this.get_BehaviorStateHiddenField()).val(Ext.encode(this._BehaviorState));
    },
    invoke: function (args, onComplete$delegate, context, onError$delegate, async) {
        var callbackId = this.get_UniqueID();
        if (this._AutoPostBack) {
            __doPostBack(callbackId, args);
        }
        else {
            //WebForm_DoCallback(callbackId, args, onComplete$delegate, context, onError$delegate, async);
        }
    },
    raiseItemClick: function (sender, node, item, index, e, opts) {
        var target = e.getTarget();
        if (target.tagName.toLowerCase() == 'input'
            && $(target).attr('type').toLowerCase() == 'button'
            && $(target).attr('role').toLowerCase() == 'checkbox') {
            //点击的是勾选按钮，不作处理
            return;
        }

        if (node.data.id != this._BehaviorState.SelectedId) {
            this._BehaviorState.IsSelectChanged = true;
            //保存旧的值
            this._BehaviorState.OldSelectedPath = this._BehaviorState.SelectedPath;
            this._BehaviorState.OldSelectedId = this._BehaviorState.SelectedId;
            //保存新的选中节点
            this._BehaviorState.SelectedPath = node.getPath();
            this._BehaviorState.SelectedId = node.data.id;
        }
        this.storeBehaviorState();

        if (this._TriggerPostBackEvents.NodeClick) {
            var arguments = {
                NodeId: node.data.id
            };
            this.invoke(ExtJSExtender.Util.serializeEventArgs("NodeClick", arguments), null, null, null, true);
        }
        else if (this._BehaviorState.IsSelectChanged && this._TriggerPostBackEvents.NodeSelectChanged) {
            var arguments = {
                OldSelectedPath: this._BehaviorState.OldSelectedPath,
                OldSelectedId: this._BehaviorState.OldSelectedId,
                SelectedPath: this._BehaviorState.SelectedPath,
                SelectedId: this._BehaviorState.SelectedId,
                NodeId: node.data.id
            };
            this.invoke(ExtJSExtender.Util.serializeEventArgs("NodeSelectChanged", arguments), null, null, null, true);
        }
    },
    raiseItemCheckChange: function (node, checked, opts) {
        this.storeData();

        if (this._TriggerPostBackEvents.NodeCheckChanged) {
            var arguments = {
                IsChecked: checked,
                NodeId: node.data.id
            };

            this.invoke(ExtJSExtender.Util.serializeEventArgs("NodeCheckChanged", arguments), null, null, null, true);
        }
    },
    raiseItemExpand: function (node, opts) {
        this.storeData();

        if (this._TriggerPostBackEvents.NodeExpand) {
            var arguments = {
                NodeId: node.data.id
            };

            this.invoke(ExtJSExtender.Util.serializeEventArgs("NodeExpand", arguments), null, null, null, true);
        }
    },
    raiseItemCollapse: function (node, opts) {
        this.storeData();

        if (this._TriggerPostBackEvents.NodeCollapse) {
            var arguments = {
                NodeId: node.data.id
            };

            this.invoke(ExtJSExtender.Util.serializeEventArgs("NodeCollapse", arguments), null, null, null, true);
        }
    },
    raiseBeforeLoad: function (store, operation, opts) {
        if (this._TriggerPostBackEvents.LoadChildren) {
            var arguments = {
                NodeId: operation.id
            };

            this.invoke(ExtJSExtender.Util.serializeEventArgs("LoadChildren", arguments), null, null, null, true);
            return false;   //阻止ExtTree异步获取数据
        }
    }
}

ExtJSExtender.Controls.TreePanelExtenderBehavior.registerClass('ExtJSExtender.Controls.TreePanelExtenderBehavior', Sys.UI.Control);
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();